package org.chen.translate.service;

import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.tmt.v20180321.TmtClient;
import com.tencentcloudapi.tmt.v20180321.models.TextTranslateRequest;
import com.tencentcloudapi.tmt.v20180321.models.TextTranslateResponse;
import lombok.extern.slf4j.Slf4j;
import org.chen.common.translate.dto.TranslateRequestDTO;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.ReentrantLock;

@Slf4j
@Service
public class TencentTranslateService {

    @Value("${tencent.cloud.secret-id:#{null}}")
    private String secretId;
    
    @Value("${tencent.cloud.secret-key:#{null}}")
    private String secretKey;
    
    @Value("${tencent.cloud.region:ap-beijing}")
    private String region;

    // 限流配置
    @Value("${tencent.cloud.rate-limit.requests-per-second:4}")
    private int requestsPerSecond;

    @Value("${tencent.cloud.rate-limit.max-retry-times:3}")
    private int maxRetryTimes;

    @Value("${tencent.cloud.rate-limit.retry-delay-base-ms:500}")
    private long retryDelayBaseMs;

    @Value("${tencent.cloud.rate-limit.max-wait-time-ms:30000}")
    private long maxWaitTimeMs;

    // 限流器组件
    private Semaphore rateLimiter;
    private final AtomicLong lastRequestTime = new AtomicLong(0);
    private final ReentrantLock requestLock = new ReentrantLock();

    // 请求间隔时间（毫秒）
    private long requestIntervalMs;

    @PostConstruct
    private void initRateLimiter() {
        this.rateLimiter = new Semaphore(requestsPerSecond);
        this.requestIntervalMs = 1000L / requestsPerSecond; // 计算请求间隔
        log.info("腾讯翻译限流器初始化完成，每秒最多{}个请求，请求间隔{}ms", requestsPerSecond, requestIntervalMs);
    }

    /**
     * 执行文本翻译（带高并发限流处理）
     * @param translateRequest 翻译请求参数
     * @return 翻译响应结果
     * @throws TencentCloudSDKException SDK异常
     */
    public TextTranslateResponse translateText(TranslateRequestDTO translateRequest) throws TencentCloudSDKException {
        long startTime = System.currentTimeMillis();

        try {
            // 执行带限流的翻译
            return executeWithRateLimit(translateRequest);
        } catch (Exception e) {
            long duration = System.currentTimeMillis() - startTime;
            log.error("腾讯翻译翻译失败，耗时{}ms，错误：{}", duration, e.getMessage());
            throw e;
        }
    }

    /**
     * 带限流和重试的核心执行方法
     */
    private TextTranslateResponse executeWithRateLimit(TranslateRequestDTO translateRequest) throws TencentCloudSDKException {
        int retryCount = 0;
        TencentCloudSDKException lastException = null;

        while (retryCount <= maxRetryTimes) {
            try {
                // 1. 获取限流许可（带超时）
                boolean acquired = rateLimiter.tryAcquire(maxWaitTimeMs, TimeUnit.MILLISECONDS);
                if (!acquired) {
                    throw new TencentCloudSDKException("系统繁忙，请稍后再试（等待超时）");
                }

                try {
                    // 2. 确保请求间隔（防止瞬间突发）
                    enforceRequestInterval();

                    // 3. 执行实际翻译
                    return performTranslation(translateRequest);

                } finally {
                    // 4. 延迟释放许可，确保限流效果
                    schedulePermitRelease();
                }

            } catch (TencentCloudSDKException e) {
                lastException = e;

                // 判断是否为频率限制错误
                if (isRateLimitError(e) && retryCount < maxRetryTimes) {
                    retryCount++;
                    long delayMs = calculateRetryDelay(retryCount);

                    log.warn("遇到频率限制错误，第{}次重试，延迟{}ms。错误：{}",
                            retryCount, delayMs, e.getMessage());

                    try {
                        Thread.sleep(delayMs);
                    } catch (InterruptedException ie) {
                        Thread.currentThread().interrupt();
                        throw new TencentCloudSDKException("腾讯翻译翻译被中断", ie);
                    }
                } else {
                    // 非频率限制错误或重试次数用完，直接抛出
                    throw e;
                }

            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                throw new TencentCloudSDKException("等待限流许可被中断", e);
            }
        }

        // 所有重试都失败了
        if (lastException != null) {
            throw lastException;
        } else {
            throw new TencentCloudSDKException("腾讯翻译翻译失败，已达到最大重试次数");
        }
    }

    /**
     * 确保请求间隔 - 防止瞬间大量请求
     */
    private void enforceRequestInterval() {
        requestLock.lock();
        try {
            long currentTime = System.currentTimeMillis();
            long lastTime = lastRequestTime.get();
            long timeSinceLastRequest = currentTime - lastTime;

            if (timeSinceLastRequest < requestIntervalMs) {
                long sleepTime = requestIntervalMs - timeSinceLastRequest;
                try {
                    Thread.sleep(sleepTime);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    log.warn("请求间隔等待被中断");
                }
            }

            lastRequestTime.set(System.currentTimeMillis());
        } finally {
            requestLock.unlock();
        }
    }

    /**
     * 执行实际的翻译请求
     */
    private TextTranslateResponse performTranslation(TranslateRequestDTO translateRequest) throws TencentCloudSDKException {
        try {
            // 创建凭证对象
            Credential credential = createCredential();

            // 创建翻译客户端
            TmtClient tmtClient = new TmtClient(credential, region);

            // 构建翻译请求
            TextTranslateRequest request = buildTranslateRequest(translateRequest);

            // 执行翻译
            TextTranslateResponse response = tmtClient.TextTranslate(request);

            log.debug("腾讯翻译翻译请求成功，原文长度：{}，译文长度：{}",
                    translateRequest.getSourceText().length(),
                    response.getTargetText().length());

            return response;

        } catch (TencentCloudSDKException e) {
            log.error("腾讯云翻译API调用失败：{}", e.getMessage());
            throw e;
        }
    }

    /**
     * 延迟释放许可，确保限流效果
     */
    private void schedulePermitRelease() {
        // 使用异步方式延迟释放，避免阻塞当前线程
        new Thread(() -> {
            try {
                Thread.sleep(requestIntervalMs);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            } finally {
                rateLimiter.release();
            }
        }).start();
    }

    /**
     * 判断是否为频率限制错误
     */
    private boolean isRateLimitError(TencentCloudSDKException e) {
        if (e.getMessage() == null) return false;

        String message = e.getMessage().toLowerCase();
        return message.contains("frequency limit") ||
                message.contains("rate limit") ||
                message.contains("request times equals") ||
                message.contains("exceeds the frequency limit");
    }

    /**
     * 计算重试延迟时间（指数退避）
     */
    private long calculateRetryDelay(int retryCount) {
        return retryDelayBaseMs * (1L << (retryCount - 1)); // 指数退避：500ms, 1000ms, 2000ms
    }

    /**
     * 获取当前限流器状态（监控用）
     */
    public String getRateLimitStatus() {
        return String.format("可用许可: %d/%d, 等待队列: %d, 上次请求时间: %d",
                rateLimiter.availablePermits(),
                requestsPerSecond,
                rateLimiter.getQueueLength(),
                System.currentTimeMillis() - lastRequestTime.get());
    }

    /**
     * 手动重置限流器（紧急情况使用）
     */
    public void resetRateLimiter() {
        log.warn("手动重置限流器");
        this.rateLimiter = new Semaphore(requestsPerSecond);
        this.lastRequestTime.set(0);
    }

    /**
     * 创建腾讯云凭证
     * @return Credential对象
     */
    private Credential createCredential() {
        // 优先从环境变量获取密钥，其次从配置文件获取
        String finalSecretId = secretId != null ? secretId : System.getenv("TENCENTCLOUD_SECRET_ID");
        String finalSecretKey = secretKey != null ? secretKey : System.getenv("TENCENTCLOUD_SECRET_KEY");

        if (finalSecretId == null || finalSecretKey == null) {
            throw new IllegalStateException("腾讯云密钥未配置，请在环境变量或配置文件中设置TENCENTCLOUD_SECRET_ID和TENCENTCLOUD_SECRET_KEY");
        }

        return new Credential(finalSecretId, finalSecretKey);
    }

    /**
     * 构建翻译请求对象
     * @param dto 前端传来的请求DTO
     * @return TextTranslateRequest对象
     */
    private TextTranslateRequest buildTranslateRequest(TranslateRequestDTO dto) {
        TextTranslateRequest request = new TextTranslateRequest();

        // 设置必需参数
        request.setSourceText(dto.getSourceText());
        request.setSource(dto.getSource());
        request.setTarget(dto.getTarget());

        // 设置可选参数
        if (dto.getProjectId() != null) {
            request.setProjectId(dto.getProjectId());
        }

        if (dto.getUntranslatedText() != null) {
            request.setUntranslatedText(dto.getUntranslatedText());
        }

        // 设置术语库ID列表（需要过滤null值）
        if (dto.getTermRepoIDList() != null && !dto.getTermRepoIDList().isEmpty()) {
            String[] termRepoIds = dto.getTermRepoIDList().stream()
                    .filter(id -> id != null && !id.trim().isEmpty())
                    .toArray(String[]::new);
            if (termRepoIds.length > 0) {
                request.setTermRepoIDList(termRepoIds);
            }
        }

        // 设置句库ID列表（需要过滤null值）
        if (dto.getSentRepoIDList() != null && !dto.getSentRepoIDList().isEmpty()) {
            String[] sentRepoIds = dto.getSentRepoIDList().stream()
                    .filter(id -> id != null && !id.trim().isEmpty())
                    .toArray(String[]::new);
            if (sentRepoIds.length > 0) {
                request.setSentRepoIDList(sentRepoIds);
            }
        }

        return request;
    }
}